﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using HorseRaceRe.Code.Interfaces;
using Mono.CSharp;

namespace HorseRaceRe.Code.Models
{
    /// <summary>
    /// 赛马场地信息
    /// </summary>
    public class RaceGroundInfo
    {
        public int GroundLong { get; set; } = 16;

        //public string BackGroundImgPath { get; set; }

        //public string RaceTrackImgPath { get; set; }
        //public string RaceBannerImgPath { get; set; }

        public List<string> EnableEvents { get; set; } = new List<string>();

        public int MaxStep { get; set; } = 4;

        public double EventPossibility { get; set; } = 0.6;

        public Char TrackStrUnit { get; set; } = '=';
    }

    public class RaceGround
    {
        private Guid GUID;
        private bool isOn = false; //是否开启
        private List<EventInfo> events = new List<EventInfo>(); //载入的场地使用Events

        public RaceGround(RaceGroundInfo info)
        {
            Info = info;
            GUID = Guid.NewGuid();
            //Load events in info
            info.EnableEvents.ForEach(e =>
            {
                if (e.EndsWith(".cs") is false)
                    e += ".cs";
                var find = App.LoadedEvents.Find(le => le.Info.Name == e);
                if (find != null)
                    events.Add(find);
                //Todo Log An EventScript(Ground Use) Not Find
            });
        }

        public List<Horse> Horses = new List<Horse>(); //比赛中马儿的列表

        public RaceGroundInfo Info; //场地信息

        private List<HorseBase> _rankList = new List<HorseBase>(); //最终排名

        /// <summary>
        /// 比赛前的加入马儿
        /// </summary>
        /// <param name="h"></param>
        /// <param name="qq"></param>
        /// <returns></returns>
        public bool AddHorse(HorseBase h, string qq)
        {
            if (isOn)
                return false; //已经开启，无法添加马儿

            if (this.Horses.Exists(match => match.Owner == qq) is false)
            {
                this.Horses.Add(new Horse(h, qq));
                return true;
            }
            else
            {
                return false; //已经存在你的马儿了！
            }
        }

        /// <summary>
        /// 开始比赛
        /// </summary>
        /// <returns>返回是否开启成功(若已经开启返回False)</returns>
        public bool Start()
        {
            if (isOn)
            {
                return false;
            }
            else
            {
                isOn = true;
                return true;
            }
        }

        public bool Process(out List<string> eventmessage, bool dealwithE)
        {
            try
            {
                return Process(out eventmessage);
            }
            catch (Exception e)
            {
                File.AppendAllLines("HorseRaceRe.log",new []{ e.Message});

                eventmessage = null;
                return true;
            }
        }
        
        /// <summary>
        /// 一次移动
        /// </summary>
        /// <returns>返回是否所有有马儿抵达了终点Or结束比赛</returns>
        public bool Process(out List<string> eventmsgs)
        {
            var _eventmsgs = new List<string>();
            var allEnd = false;
            List<Horse> luckyHorse = new List<Horse>();

            if (Info.EnableEvents.Count != 0)
            {
                Horses.ForEach(x =>
                {
                    if (new Random(Guid.NewGuid().GetHashCode()).NextDouble() <= Info.EventPossibility)
                    {
                        //Chose the lucky horse 
                        luckyHorse.Add(x);
                    }
                });
            }

            foreach (var horse in Horses.Where(hor => !luckyHorse.Contains(hor)))
            {
                if (horse.Status == HorseStatus.Died)
                {
                    //TODO 复活???
                }
                else
                {
                    //随机的前进步数
                    var step = (int) (new Random(Guid.NewGuid().GetHashCode()).NextDouble() * Info.MaxStep);
                    horse.Position += step;
                    if (horse.Position > this.Info.GroundLong)
                    {
                        horse.Position = Info.GroundLong;
                    }
                }
            }

            //LuckEvent 对采用随机事件的Process使用。
            luckyHorse.ForEach(
                x =>
                {
                    //使用随机事件
                    var step = (int) (new Random(Guid.NewGuid().GetHashCode()).NextDouble() * Info.MaxStep);
                    var raceGround_c = this;
                    var s = events[new Random(Guid.NewGuid().GetHashCode()).Next(events.Count)].Event?
                        .Process(ref raceGround_c, ref x, ref step);
                    _eventmsgs.Add($"[{x.Base.Name}]"+s);

                    x.Position += step;
                    if (x.Position > this.Info.GroundLong)
                    {
                        x.Position = Info.GroundLong;
                    }

                    var index = raceGround_c.Horses.FindIndex(h => h.Owner == x.Owner);
                    raceGround_c.Horses[index] = x;
                    //改变List中所有Horse 以及 自身
                    for (var i = 0; i < Horses.Count; i++)
                    {
                        Horses[i] = raceGround_c.Horses[i]; //重新赋值
                    }
                });

            //防止Position过高过低
            foreach (var horse in Horses)
            {
                if (horse.Position < 0)
                {
                    horse.Position = 0;
                }

                if (horse.Position > Info.GroundLong)
                    horse.Position = Info.GroundLong;
            }


            //判断是否都结束了
            foreach (var horse in Horses)
            {
                if (horse.Position == this.Info.GroundLong)
                    allEnd = true;
            }

            if (Horses.TrueForAll(horse => horse.Status == HorseStatus.Died))
                allEnd = true;

            eventmsgs = _eventmsgs;
            return allEnd;
        }

        public string GenerateStr(List<string> eventmsgs)
        {
            var msg = new StringBuilder();

            if (eventmsgs != null)
            {
                msg.AppendLine(String.Join("\n", eventmsgs));
            }


            Horses.ForEach(x =>
            {
                var line = new string(Info.TrackStrUnit, Info.GroundLong);
                line = line.Insert(Info.GroundLong - (x.Position ), x.Base.Name);
                msg.AppendLine(line);
            });
            return msg.ToString();
        }

        // public string GenerateImg()
        // {
        //     //先绘制Back部分 包括banner + 跑道
        //     Bitmap bitmap = new Bitmap(1000, 400 + Horses.Count * 100);
        //     Graphics g = Graphics.FromImage(bitmap);
        //
        //     var backRect = new Rectangle(0, 0, 1000, 400 + Horses.Count * 100);
        //     var topBannerRect = new Rectangle(0, 0, 1000, 400);
        //     g.FillRectangle(Brushes.WhiteSmoke, backRect);
        //
        //     if (String.IsNullOrEmpty(this.Info.RaceBannerImgPath) is false)
        //     {
        //         var img = Image.FromFile(Info.RaceBannerImgPath);
        //         g.DrawImage(img, 0, 0);
        //         //绘制顶部 1000*400的Banner区域
        //     }
        //     else
        //     {
        //     }
        //
        //     var trackimg = Image.FromFile(Info.RaceTrackImgPath ?? "Config\\HorseRaceRe\\Resources\\跑道.jpg");
        //     for (var i = 0; i < Horses.Count; i++)
        //     {
        //         PointF p = new PointF(0, 400 + i * 100);
        //         g.DrawImage(trackimg, p);
        //         //绘制 10*100 的开始点
        //         p.X += 200; //在200的位置绘制开始线
        //         var startRect = new Rectangle((int) p.X, (int) p.Y, 10, 100);
        //         g.FillRectangle(Brushes.WhiteSmoke, startRect);
        //         //绘制终点线
        //         p.X += 690;
        //         var endRect = new Rectangle((int) p.X, (int) p.Y, 10, 100);
        //         g.FillRectangle(Brushes.WhiteSmoke, endRect);
        //
        //     }
        //     //跑道绘制完成
        //     
        //     
        //
        //     for (var i = 0; i < Horses.Count; i++)
        //     {
        //         Horse horse = Horses[i];
        //         Point sp = new Point(0, 400 + i * 100);//跑道起始位置
        //
        //         //先绘制一个小马64*64基础图标
        //         Bitmap hbm = new Bitmap(100, 100);
        //
        //         Graphics hb = Graphics.FromImage(hbm);
        //
        //         var head = Image.FromFile(horse.Base.DisplayImgPath ?? "Config\\HorseRaceRe\\Resources\\nullimg.png");
        //         using (head)
        //         {
        //             hb.DrawImage(head, 18, 36);
        //         }
        //
        //         //绘制名字区域
        //         var nameRect = new Rectangle(0, 10, 100, 26);
        //         var font = new Font(FontFamily.GenericSerif,18,GraphicsUnit.Pixel);
        //         var strF = new StringFormat(){Alignment = StringAlignment.Center,LineAlignment = StringAlignment.Center};
        //         hb.DrawString(horse.Base.Name,font,Brushes.WhiteSmoke, nameRect,strF);
        //
        //         hb.Save();
        //         hb.Dispose();
        //         //释放小马Graphics
        //
        //         if (horse.Position == 0)
        //         {
        //             //在跑道前绘制
        //             sp.X += 50;
        //         }else if (Math.Abs(horse.Position - Info.GroundLong) == 0)
        //         {
        //             sp.X = 900;
        //         }
        //         else
        //         {
        //             //开始跑了
        //
        //             sp.X += 210;
        //             sp.X += (int)((1000 - 400) / Info.GroundLong * horse.Position);
        //
        //         }
        //             g.DrawImage(hbm,sp);
        //     }
        //
        //
        //     g.Save();
        //     if (Directory.Exists("Config\\HorseRaceRe\\Temp\\"+GUID.ToString()) is false)
        //         Directory.CreateDirectory("Config\\HorseRaceRe\\Temp\\"+GUID.ToString());
        //     var _p = $"Config\\HorseRaceRe\\Temp\\{GUID}\\{DateTime.Now.Ticks}.jpg";
        //     bitmap.Save(_p);
        //     bitmap.Dispose();
        //     g.Dispose();
        //     return _p;
        // }
    }
}